home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_203 / gurusguide / serial.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  201 lines

  1. /************************************************************************
  2. **********                                                     **********
  3. **********           S E R I A L   I N T E R R U P T           **********
  4. **********           -------------------------------           **********
  5. **********                                                     **********
  6. **********        Copyright (C) 1988 Sassenrath Research       **********
  7. **********                All Rights Reserved.                 **********
  8. **********                                                     **********
  9. **********    Example from the "Guru's Guide, Meditation #1"   **********
  10. **********                                                     **********
  11. *************************************************************************
  12. **                                                                     **
  13. **                            - NOTICE -                               **
  14. **                                                                     **
  15. **  The "Guru's Guide, Meditation #1" contains detailed information    **
  16. **  about Amiga interrupts as well as a complete discussion of this    **
  17. **  and other examples.  Meditation #1 and all of its examples were    **
  18. **  written by Carl Sassenrath, the architect of Amiga's multitasking  **
  19. **  operating system.  Copies of the "Guru's Guide" may be obtained    **
  20. **  from:                                                              **
  21. **           GURU'S GUIDE, P.O. BOX 1510, UKIAH, CA 95482              **
  22. **                                                                     **
  23. **  Please include a check for $14.95, plus $1.50 shipping ($4.00 if   **
  24. **  outside North America).  CA residents add 6% sales tax.            **
  25. **                                                                     **
  26. **  This example may be used for any purposes, commercial, personal,   **
  27. **  public, and private, so long as ALL of the above text, copyright,  **
  28. **  mailing address, and this notice are retained in their entirety.   **
  29. **                                                                     **
  30. **  THIS EXAMPLE IS PROVIDED WITHOUT WARRANTY OF ANY KIND.             **
  31. **                                                                     **
  32. ************************************************************************/
  33.  
  34. /*
  35. **  IMPORTANT WARNING:
  36. **
  37. **  This program will interfere with the proper operation of the Amiga's
  38. **  Serial Device Driver.  Use with care.
  39. */
  40.  
  41. /*
  42. **  COMPILATION NOTE:
  43. **
  44. **  Compiled under MANX AZTEC C 3.6A.  Use the +L compiler option
  45. **  and the "c32" library.  Link with intrsup.o.
  46. */
  47.  
  48.  
  49. #include <exec/exec.h>
  50. #include <hardware/intbits.h>
  51. #include <hardware/custom.h>
  52. #include <stdio.h>
  53.  
  54. #define    TIMEOUT 240        /* 4 seconds */
  55. #define    BAUD_RATE 372        /* 9600 baud */
  56.  
  57. char IntrName[] = "serial.example";
  58.  
  59. struct    SigInfo
  60. {
  61.     short    buffer;        /* char buffer */
  62.     short    intrmask;    /* intr to reset */
  63.     long    signal;        /* signal mask */
  64.     struct    Task *task;    /* task to signal */
  65.     long    sig;        /* sig bit to free */
  66.     struct    Interrupt *intr;
  67. } Serial, TimeOut;
  68.  
  69.  
  70. /* Interrupt Processing Code */
  71. VOID    SerialCode();
  72. VOID    TimeOutCode();
  73. #asm
  74. TIMEOUT        equ    240
  75. EXECBASE    equ    4
  76. intreq        EQU    $9C    ; interrupt request
  77. serdatr        EQU    $18    ; serial data read
  78.  
  79.         public    _LVOSignal
  80.  
  81. _TimeOutCode:
  82.         subq.w    #1,(a1)            ; decr timeout
  83.         move.w    (a1),d0
  84.         bge.s    exit            ; expired?
  85.         move.w    #TIMEOUT,(a1)        ; reset timeout
  86.         addq.l    #4,a1            ; adjust pointer
  87.         bra.s    signal
  88.  
  89. _SerialCode:
  90.         move.w    serdatr(a0),(a1)+    ; get the char
  91.         move.w    (a1)+,intreq(a0)     ; clear the request
  92.  
  93. signal:
  94.         move.l    (a1)+,d0         ; the signal
  95.         move.l    (a1)+,a1          ; the task
  96.         move.l    EXECBASE,a6
  97.         jsr    _LVOSignal(a6)
  98. exit:
  99.         moveq    #0,d0            ; Z-flag - do next server
  100.         rts
  101. #endasm
  102.  
  103.  
  104.  
  105. main()
  106. {
  107.     extern long Wait();
  108.     extern int Enable_Abort;
  109.     long waitsigs;
  110.     char c;
  111.  
  112.     Enable_Abort = 0;    /* prevent a CTRL-C */
  113.  
  114.     /* Required for proper clean-up: */
  115.     Serial.sig = TimeOut.sig = -1;
  116.  
  117.     MakeSigIntr(IntrName,INTB_RBF,0,&SerialCode,&Serial);
  118.     MakeSigIntr(IntrName,INTB_VERTB,-60,&TimeOutCode,&TimeOut);
  119.  
  120.     /* Set serial baud rate to 9600 */
  121.     custom.serper = BAUD_RATE;
  122.  
  123.     AddHandler(INTB_RBF,Serial.intr);
  124.     EnableIntr(INTB_RBF);
  125.  
  126.     TimeOut.buffer = TIMEOUT;
  127.     AddIntServer(INTB_VERTB,TimeOut.intr);
  128.  
  129.     while (TRUE)
  130.     {
  131.         waitsigs = Wait(Serial.signal | TimeOut.signal);
  132.  
  133.         if (waitsigs & Serial.signal)
  134.         {
  135.             c = (char)Serial.buffer;
  136.             if (c == 3) break;    /* CTRL-C to stop */
  137.             if (c == 13) c = 10;    /* change CR to LF */
  138.             putchar(c);
  139.             fflush(stdout);        /* force it out */
  140.  
  141.             /* Reset timeout */
  142.             TimeOut.buffer = TIMEOUT;
  143.         }
  144.  
  145.         if (waitsigs & TimeOut.signal)
  146.             puts("\nTIMEOUT!");
  147.     }
  148.  
  149.     DisableIntr(INTB_RBF);
  150.     MainExit(0);
  151. }
  152.  
  153.  
  154. MakeSigIntr(iname,ibit,pri,iproc,isig)
  155.     char *iname;
  156.     int ibit;
  157.     VOID (*iproc)();
  158.     register struct SigInfo *isig;
  159. {
  160.     extern    struct Task *FindTask();
  161.     extern struct Interrupt *MakeIntr();
  162.     struct Interrupt *intr;
  163.  
  164.     isig->sig = AllocSignal(-1);
  165.     if (isig->sig == -1) MainExit(100);
  166.  
  167.     intr = MakeIntr(iname,pri,iproc,isig);
  168.     if (intr == NULL) MainExit(101);
  169.  
  170.     isig->buffer = 0;
  171.     isig->intrmask = 1 << ibit;
  172.     isig->signal = 1 << isig->sig;
  173.     isig->task = FindTask(NULL);
  174.     isig->intr = intr;
  175. }
  176.  
  177.  
  178. MainExit(error)
  179.     int error;
  180. {
  181.     puts("Terminate!");
  182.  
  183.     if (Serial.intr != NULL)
  184.     {
  185.         RemHandler(INTB_RBF, Serial.intr);
  186.         FreeIntr(Serial.intr);
  187.     }
  188.  
  189.     if (TimeOut.intr != NULL)
  190.     {
  191.         RemIntServer(INTB_VERTB, TimeOut.intr);
  192.         FreeIntr(TimeOut.intr);
  193.     }
  194.  
  195.     if (Serial.sig != -1) FreeSignal(Serial.sig);
  196.  
  197.     if (TimeOut.sig != -1) FreeSignal(TimeOut.sig);
  198.  
  199.     exit(error);
  200. }
  201.